package com.ruoyi.withdraw.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.distributionConfig.domain.DistributionConfig;
import com.ruoyi.distributionConfig.service.IDistributionConfigService;
import com.ruoyi.wallet.domain.DistributionWallet;
import com.ruoyi.wallet.service.IDistributionWalletService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.withdraw.mapper.DistributionWithdrawMapper;
import com.ruoyi.withdraw.domain.DistributionWithdraw;
import com.ruoyi.withdraw.service.IDistributionWithdrawService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 提现申请Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-10-11
 */
@Service
public class DistributionWithdrawServiceImpl implements IDistributionWithdrawService 
{
    @Autowired
    private DistributionWithdrawMapper distributionWithdrawMapper;

    @Autowired
    private IDistributionConfigService distributionConfigService;

    @Autowired
    private IDistributionWalletService distributionWalletService;

    /**
     * 查询提现申请
     * 
     * @param withdrawId 提现申请主键
     * @return 提现申请
     */
    @Override
    public DistributionWithdraw selectDistributionWithdrawByWithdrawId(Long withdrawId)
    {
        return distributionWithdrawMapper.selectDistributionWithdrawByWithdrawId(withdrawId);
    }

    /**
     * 查询提现申请列表
     * 
     * @param distributionWithdraw 提现申请
     * @return 提现申请
     */
    @Override
    public List<DistributionWithdraw> selectDistributionWithdrawList(DistributionWithdraw distributionWithdraw)
    {
        return distributionWithdrawMapper.selectDistributionWithdrawList(distributionWithdraw);
    }

    /**
     * 新增提现申请
     * 
     * @param distributionWithdraw 提现申请
     * @return 结果
     */
    @Override
    public int insertDistributionWithdraw(DistributionWithdraw distributionWithdraw)
    {
        distributionWithdraw.setCreateTime(DateUtils.getNowDate());
        return distributionWithdrawMapper.insertDistributionWithdraw(distributionWithdraw);
    }

    /**
     * 修改提现申请
     * 
     * @param distributionWithdraw 提现申请
     * @return 结果
     */
    @Override
    public int updateDistributionWithdraw(DistributionWithdraw distributionWithdraw)
    {
        distributionWithdraw.setUpdateTime(DateUtils.getNowDate());
        return distributionWithdrawMapper.updateDistributionWithdraw(distributionWithdraw);
    }

    /**
     * 批量删除提现申请
     * 
     * @param withdrawIds 需要删除的提现申请主键
     * @return 结果
     */
    @Override
    public int deleteDistributionWithdrawByWithdrawIds(Long[] withdrawIds)
    {
        return distributionWithdrawMapper.deleteDistributionWithdrawByWithdrawIds(withdrawIds);
    }

    /**
     * 删除提现申请信息
     * 
     * @param withdrawId 提现申请主键
     * @return 结果
     */
    @Override
    public int deleteDistributionWithdrawByWithdrawId(Long withdrawId)
    {
        return distributionWithdrawMapper.deleteDistributionWithdrawByWithdrawId(withdrawId);
    }

    /**
     * 提交提现申请
     * @param distributorId 分销员ID
     * @param amount 提现金额
     * @param paymentType 支付方式
     * @param paymentAccount 收款账号
     * @param paymentName 收款人姓名
     * @return 提现申请结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public DistributionWithdraw submitWithdrawApplication(Long distributorId, BigDecimal amount,
                                                          String paymentType, String paymentAccount, String paymentName) {
        // 1. 获取分销配置，检查最低提现金额
        DistributionConfig config = distributionConfigService.selectDistributionConfigByConfigId(1L);
        if (config != null && config.getMinWithdrawAmount() != null) {
            if (amount.compareTo(config.getMinWithdrawAmount()) < 0) {
                throw new ServiceException("提现金额不能低于最低提现金额: " + config.getMinWithdrawAmount());
            }
        }

        // 2. 查询分销员钱包
        DistributionWallet wallet = distributionWalletService.selectWalletByDistributorId(distributorId);
        if (wallet == null) {
            throw new ServiceException("未找到分销员钱包信息");
        }

        // 3. 校验可用余额
        if (wallet.getAvailableBalance() == null || wallet.getAvailableBalance().compareTo(amount) < 0) {
            throw new ServiceException("可用余额不足，当前可用余额: " + wallet.getAvailableBalance());
        }

        // 4. 创建提现申请记录
        DistributionWithdraw withdraw = new DistributionWithdraw();

        withdraw.setWithdrawCode(IdUtils.generateWithdrawCode()); // 提现编号
        // withdraw.setWithdrawCode("WD" + System.currentTimeMillis() + UUID.randomUUID().toString().substring(0, 6).toUpperCase());

        withdraw.setDistributorId(distributorId);
        withdraw.setAmount(amount);
        withdraw.setPaymentType(paymentType);
        withdraw.setPaymentAccount(paymentAccount);
        withdraw.setPaymentName(paymentName);
        withdraw.setAuditStatus("0"); // 待审核
        withdraw.setStatus("0"); // 上架状态
        withdraw.setDelFlag("0"); // 未删除
        withdraw.setVersion(1L);
        withdraw.setCreateTime(new Date());
        withdraw.setCreateBy("system");

        // 5. 计算手续费和实际到账金额（示例：手续费为0，实际到账金额等于申请金额）
        // 可根据实际业务需求调整手续费计算逻辑
        BigDecimal fee = BigDecimal.ZERO; // 手续费
        BigDecimal actualAmount = amount.subtract(fee); // 实际到账金额

        withdraw.setFee(fee);
        withdraw.setActualAmount(actualAmount);

        // 6. 保存提现申请
        int result = insertDistributionWithdraw(withdraw);
        if (result <= 0) {
            throw new ServiceException("提现申请提交失败");
        }

        return withdraw;
    }

    /**
     * 审核提现申请
     * @param withdrawId 提现申请ID
     * @param auditStatus 审核状态 1-通过 4-拒绝
     * @param auditRemark 审核备注
     * @param auditorId 审核人ID
     * @return 审核结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean auditWithdrawApplication(Long withdrawId, String auditStatus, String auditRemark, Long auditorId) {
        // 1. 查询提现申请
        DistributionWithdraw withdraw = selectDistributionWithdrawByWithdrawId(withdrawId);
        if (withdraw == null) {
            throw new ServiceException("提现申请不存在");
        }

        // 2. 检查当前状态是否为待审核
        if (!"0".equals(withdraw.getAuditStatus())) {
            throw new ServiceException("提现申请状态不正确，无法审核");
        }

        // 3. 更新审核信息
        withdraw.setAuditStatus(auditStatus);
        withdraw.setAuditRemark(auditRemark);
        withdraw.setAuditorId(auditorId);
        withdraw.setAuditTime(new Date());
        withdraw.setUpdateTime(new Date());
        withdraw.setUpdateBy(SecurityUtils.getUsername());

        // 4. 如果审核通过，冻结相应金额
        if ("1".equals(auditStatus)) {
            // 查询钱包
            DistributionWallet wallet = distributionWalletService.selectWalletByDistributorId(withdraw.getDistributorId());
            if (wallet == null) {
                throw new ServiceException("未找到分销员钱包信息");
            }

            // 检查余额是否足够冻结
            if (wallet.getAvailableBalance() == null || wallet.getAvailableBalance().compareTo(withdraw.getAmount()) < 0) {
                throw new ServiceException("可用余额不足，无法冻结资金");
            }

            // 冻结金额：从可用余额转移到冻结余额
            wallet.setAvailableBalance(wallet.getAvailableBalance().subtract(withdraw.getAmount()));
            wallet.setFrozenBalance(
                    wallet.getFrozenBalance() == null ? withdraw.getAmount() :
                            wallet.getFrozenBalance().add(withdraw.getAmount())
            );
            wallet.setUpdateTime(new Date());
            wallet.setUpdateBy(SecurityUtils.getUsername());

            // 更新钱包
            distributionWalletService.updateDistributionWallet(wallet);
        }

        // 5. 更新提现申请
        return updateDistributionWithdraw(withdraw) > 0;
    }

    /**
     * 执行打款操作
     * @param withdrawId 提现申请ID
     * @return 打款结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean executePayment(Long withdrawId) {
        // 1. 查询提现申请
        DistributionWithdraw withdraw = selectDistributionWithdrawByWithdrawId(withdrawId);
        if (withdraw == null) {
            throw new ServiceException("提现申请不存在");
        }

        // 2. 检查当前状态是否为审核通过
        if (!"1".equals(withdraw.getAuditStatus())) {
            throw new ServiceException("提现申请状态不正确，无法执行打款");
        }

        // 3. 调用第三方支付接口进行打款（此处为模拟实现）
        boolean paymentSuccess = processThirdPartyPayment(withdraw);
        if (!paymentSuccess) {
            throw new ServiceException("第三方支付接口调用失败");
        }

        // 4. 更新提现状态为已到账
        withdraw.setAuditStatus("3"); // 已到账
        withdraw.setPaymentTime(new Date());
        withdraw.setUpdateTime(new Date());
        withdraw.setUpdateBy(SecurityUtils.getUsername());

        // 5. 更新钱包信息：扣除冻结余额，增加累计提现金额
        DistributionWallet wallet = distributionWalletService.selectWalletByDistributorId(withdraw.getDistributorId());
        if (wallet != null) {
            // 扣除冻结余额
            if (wallet.getFrozenBalance() != null && wallet.getFrozenBalance().compareTo(withdraw.getAmount()) >= 0) {
                wallet.setFrozenBalance(wallet.getFrozenBalance().subtract(withdraw.getAmount()));
            }

            // 增加累计提现金额
            wallet.setTotalWithdraw(
                    wallet.getTotalWithdraw() == null ? withdraw.getAmount() :
                            wallet.getTotalWithdraw().add(withdraw.getAmount())
            );

            wallet.setUpdateTime(new Date());
            wallet.setUpdateBy(SecurityUtils.getUsername());

            distributionWalletService.updateDistributionWallet(wallet);
        }

        // 6. 更新提现申请
        return updateDistributionWithdraw(withdraw) > 0;
    }

    /**
     * 模拟第三方支付接口调用
     * 实际开发中需要根据具体的支付渠道（微信、支付宝、银行卡等）实现具体的打款逻辑
     * @param withdraw 提现申请
     * @return 打款结果
     */
    private boolean processThirdPartyPayment(DistributionWithdraw withdraw) {
        // 这里应该调用实际的第三方支付接口进行打款操作
        // 根据 paymentType（支付方式）调用不同的支付接口
        // 例如：微信企业付款、支付宝转账、银联转账等

        // 模拟支付成功
        try {
            Thread.sleep(1000); // 模拟网络延迟
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 查询分销员的提现记录
     * @param distributorId 分销员ID
     * @return 提现记录列表
     */
    @Override
    public List<DistributionWithdraw> selectWithdrawListByDistributorId(Long distributorId) {
        DistributionWithdraw query = new DistributionWithdraw();
        query.setDistributorId(distributorId);
        return selectDistributionWithdrawList(query);
    }
}
